gdkwindow: subsurface in gdk_window_get_parent()
authorOlivier Fourdan <ofourdan@redhat.com>
Wed, 1 Feb 2017 14:09:52 +0000 (15:09 +0100)
committerOlivier Fourdan <ofourdan@redhat.com>
Thu, 30 Mar 2017 13:46:25 +0000 (15:46 +0200)
When the GtkWidget hierarchy does not match the GdkWindow hierarchy, the
GtkWidget code may find a common ancestor that cannot be found while
traversing the GdkWindow tree using gdk_window_get_parent().

This happens with for example on Wayland, a GtkPopover has another
GtkPopover as parent, in this case, the GdkWindow parent is the root
window, whereas the GtkWidget parent is the other GtkPopover.

That confuses the gtk_widget_translate_coordinates() logic which will
bail out in this case and won't return the translated coordinates.

Make gdk_window_get_effective_parent() aware of subsurfaces and use the
transient_for which represents the actual parent (whereas the parent
might be pointing to the root window).

Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=774148

gdk/gdkwindow.c

index fe14493ea6484e4ca5b84a71050aa534efec938a..59d21d4f2d7e4cbd9d4afb8f33e8191452b29c55 100644 (file)
@@ -456,6 +456,12 @@ gdk_window_get_property (GObject    *object,
     }
 }
 
+static gboolean
+gdk_window_is_subsurface (GdkWindow *window)
+{
+   return window->window_type == GDK_WINDOW_SUBSURFACE;
+}
+
 static GdkWindow *
 gdk_window_get_impl_window (GdkWindow *window)
 {
@@ -1729,7 +1735,10 @@ gdk_window_get_parent (GdkWindow *window)
 {
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
 
-  return window->parent;
+  if (gdk_window_is_subsurface (window))
+    return window->transient_for;
+  else
+    return window->parent;
 }
 
 /**